gusucode.com > VC++ RingSDK界面库 > VC++ RingSDK界面库/code/example/tutorial/05_iseebrowser/main.cpp
/********************************************************************** // // // ########## ###### ######### # ###### # // ############# ########### ######### ######### ### // ######## # ### ## ############# ## ## ##### # #### // #### ## ## ### ### ### # # ##### ##### // # ### # # ## ## ## ## ### // ## ###### ## ## #### #### # # ## // ######### ### ## ### ####### ###### ## ## ### // ###### ## ###### ## ## #### # ## #### // ####### ## ###### ## ### ## ## ### ###### // ######### ## ###### ## ###### ### ## ### # ##### // ## ###### ####### ### #### ## ## ####### ######## ## #### // ## #### ### # ### ### ## ########## ###### ## #### // ## ## ## ######### #### # ## // # ### // ## // ### // ## // // // RingSDK 演示程序(ISee图象浏览器) //作者:临风 // //版本:1.0 // //声明:本类库可以自由使用而不须对作者作出任何回报,但作者希望能得到 // 你的鼓励和支持。你可以对类库源码作出修改和改进,但希望你能在 // 修改的同时给作者一份同样的副本。 // 本类库不得用于任何商业用途,如确实需要,请与作者联系。 // //e-mail:ringphone@sina.com // //说明:不知大家是否还记得网上曾有个开源项目ISee图象浏览器,当初的目标 // 是做个超越ACDSee的浏览器出来,后来由于种种原因,变成只提供图象 // 编解码的项目,最后这个项目终止了。临风当时任这个项目的图象处理 // 组的负责人,ISee项目的夭折是很可惜的,在这里我想把这个图象浏览 // 器作为演示程序做出来,虽然比不上ACDSee,图象编解码的部分也没有 // 使用这个项目的成果代码,但也算是表达一下对项目组成员的敬意,完 // 成一个未了的心愿吧。 // //本程序在上一个演示程序基础上演示: // 创建菜单栏 // 停靠窗口/对话框 // 展现RingDIB的威力,在帮助信息对话框上演示水波效果 // 线程类的调用 // ListView控件使用 // 文件夹列表树使用 // 模拟ACDSee4.0界面,因ACDSee功能太多,因此仅实现部分功能及保留部分 // 界面,有兴趣的可以添加代码完成这些功能,记得到时发一份代码给我 // **********************************************************************/ #include "global.h" //主窗口消息绑定 BEGIN_REGMAINMSG REGCMD(CM_OPEN,OnOpen) REGCMD(CM_EXIT,OnExit) REGCMD(CM_ABOUT,OnHelp) REGNOTIFY(TVN_SELCHANGED) REGNOTIFY(TCN_SELCHANGE) REGMSG(WM_MENUSELECT) REGMSG(WM_DRAWITEM) REGMSG(WM_ACTIVATEAPP) REGCMDRANGE(CM_VIEWTD,CM_VIEWDETAIL,OnSetViewMode) REGCMDRANGE(CM_SHOWFOLDER,CM_SHOWHIDDEN,OnSetFileFilter) REGCMDRANGE(CM_COLSIZE,CM_COLTIME,OnSetColumn) REGCMDRANGE(CM_SORTEXT,CM_SORTDESC,OnSortColumn) REGMSG(WM_DESTROY) REGMSG(WM_CREATE) END_REGMSG int RingMain() { //初始化OLE库,因为后面要调用系统SHELL CoInitialize(NULL); //设置快捷键 RingApp.SetAccelTable(MAKEINTRESOURCE(IDR_ACCEL)); APP_CREATEWINDOW("Isee浏览器[演示版本]","ISeeBrowser",WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN|WS_CLIPSIBLINGS, MAKEINTRESOURCE(IDR_MAINMENU)); return RingApp.Run(); } RINGMAINMSG(WM_CREATE) { //设定支持的图象格式,目前支持以下四种格式。BMP为默认,不需要设定。 DIBREGFORMAT(GIF); DIBREGFORMAT(JPG); DIBREGFORMATS("jpeg",JPG); //设定多格式支持解码 DIBREGFORMAT(PNG); DIBREGFORMAT(PCX); //设置窗口图标 SetIcon(LoadIcon(GetInstance(),MAKEINTRESOURCE(IDI_APP))); //设置XP样式菜单 RingCoolMenu* rm = InstallXPMenu(); //创建菜单栏 RingMenuBar *menubar = NewRingObj(itemof(RingMenuBar)); menubar->LoadMenu(rm); //设置程序背景 SetDockBackGround(MAKEINTRESOURCE(IDB_BKG),TRUE); //设置菜单项图标 rm->SubMenu(2)->SubMenu(3)->SetItemIcon(CM_SORTASEC,LoadIcon(GetInstance(),MAKEINTRESOURCE(IDI_COLMARKUP))); rm->SubMenu(2)->SubMenu(3)->SetItemIcon(CM_SORTDESC,LoadIcon(GetInstance(),MAKEINTRESOURCE(IDI_COLMARKDOWN))); //CHECK一下,否则图标与选中标志图标会重叠绘制 rm->SubMenu(2)->SubMenu(3)->CheckRadioItem(CM_SORTASEC,CM_SORTDESC,CM_SORTASEC,BY_COMMAND); //设置停靠栏菜单(在工具栏停靠位置空白处的右键弹出菜单)为XP样式 rm = GetDockMenu(); if(rm) { rm->SetItemDrawFunc(FUNC_DRAWMENU_XP); rm->SetBkgColor(0x00ffffff,0x00ff8080); } //设置文件过滤标志 m_dwFilter = FILTER_FOLDER|FILTER_PIC|FILE_ATTRIBUTE_NORMAL|FILE_ATTRIBUTE_ARCHIVE; //创建状态栏 m_iconFile = NULL; m_statbar = NewRingObj(itemof(RingStatusBar)); m_statbar->Create(); int np[5] = { MAKESBPINT(0,SBTS_BORDER,SBPW_FITTEXT), //状态栏格子宽度自适应文字宽度 MAKESBPINT(0,SBTS_BORDER,SBPW_FITTEXT), MAKESBPINT(0,SBTS_BORDER,SBPW_FITTEXT), MAKESBPINT(0,SBTS_BORDER,SBPW_FITTEXT), MAKESBPINT(0,SBTS_BORDER,SBPW_STRETCH) //状态栏格子宽度自适应窗口宽度 }; m_statbar->SetParts(5,np); //创建进度条 m_progress = NewRingObj(itemof(RingProgress)); m_progress->Create(PBS_SMOOTH,RTV_FITPARENTSIZE,NULL,IDC_PROGRESS,0,0,0,0); //加入到状态栏 m_statbar->InsertItem(m_progress,4); ringDateTime rdt; char szText[40]; wsprintf(szText,"%d-%02d-%02d %02d:%02d",rdt.year(),rdt.month(),rdt.day(), rdt.hour(),rdt.minute()); m_statbar->SetValue(szText,1); //创建导航栏,RTV_FITPARENTSIZE扩展类型表示自适应父窗口尺寸 m_navbar = NewRingObj(itemof(RingTab)); m_navbar->Create(TCS_MULTILINE|TCS_HOTTRACK|TCS_OWNERDRAWFIXED, RTV_FITPARENTSIZE,NULL,IDC_NAVBAR,0,0,300,400); m_navbar->InsertTabs("文件夹|相册|收藏夹|搜索"); //创建文件夹列表树,父窗口为m_navbar,因此需调用m_navbar->NewRingObj m_dirtree = m_navbar->NewRingObj(itemof(RingDirTree)); m_dirtree->Create(IDC_FOLDERTREE); //自适应父窗口尺寸 m_dirtree->SetAutoSize(); m_dirtree->ListDir(); //绑定文件夹列表树到第一个标签 m_navbar->SetTabToWnd(0,m_dirtree); //创建侧边栏 m_navbar->EnableDockSize("导航栏",200,400,TBS_FLAG_DOCKLEFT); //创建导航子窗口 m_tab = NewRingObj(itemof(RingTabEx)); m_tab->Create(TCS_HOTTRACK|TCS_OWNERDRAWFIXED, RTV_FITPARENTSIZE,NULL,IDC_NAVPANE,0,0,300,400); m_tab->InsertTabs("文件|查看|属性"); NavPane = m_tab->NewRingObj(NavPane,TRUE); NavPane->Create("导航窗口","ISeeNavPane",WS_CHILD,0,400,400,200,200); m_tab->SetTabToWnd(0,NavPane); m_tab->SetTabToWnd(1,NavPane); m_tab->Select(0); //获取文件列表栏 m_fileview = NavPane->m_fileview; //创建图片浏览器 child = NewRingObj(child,TRUE); child->Create("图片浏览器","ISeeViwer",WS_CHILD,0,0,0,200,200); child->EnableDockSize("图片浏览器",200,200); //停靠到左下方 RECT rc; GetWindowRect(m_navbar->Handle(),&rc); ScreenToClient(m_hWnd,(LPPOINT)&rc); ScreenToClient(m_hWnd,(LPPOINT)&rc+1); rc.top = (rc.top + rc.bottom)/2; child->DockTo(TBS_FLAG_DOCKLEFT,&rc); return DefaultProc(param); } RINGMAINMSG(WM_MENUSELECT) { //在状态栏显示菜单帮助信息 return m_statbar->OnMenuHelp(param,GetMenu()); } RINGMAINMSG(WM_ACTIVATEAPP) { if(param.wParam && child && child->m_bFullScreen) { //全屏方式下设置图片窗口为活动窗口,否则该窗口接收不到按键 child->SetFocus(); } return DefaultProc(param); } RINGMAINNOTIFY(TCN_SELCHANGE) { //标签页通知消息 if(param.lpnmhdr->hwndFrom == m_navbar->Handle()) return m_navbar->OnTabSelect(param); //交由控件自己处理 else if(param.lpnmhdr->hwndFrom == m_tab->Handle()) { NavPane->SetViewMode(m_tab->GetCurSel()); return m_tab->OnTabSelect(param); } return DefaultProc(param); } RINGMAINNOTIFY(TVN_SELCHANGED) { //用户选择目录的处理,先交由控件响应 m_dirtree->OnSelectChanged(param); //填充状态拦信息 SetStatusFilePart(m_dirtree->GetSelFolderName()); m_statbar->SetValue("",3); ListFile(); return 0; } void RINGMAINMETHOD(SetStatusFilePart)(LPCTSTR lpszFile) { SHFILEINFO sfi; if(lpszFile) { SHGetFileInfo(lpszFile, 0, &sfi, sizeof(SHFILEINFO), SHGFI_ICON|SHGFI_SMALLICON|SHGFI_DISPLAYNAME); if(m_iconFile) { m_statbar->SetIcon(2,NULL); DestroyIcon(m_iconFile); } m_iconFile = sfi.hIcon; m_statbar->SetIcon(2,m_iconFile); window->m_statbar->SetValue(sfi.szDisplayName,2); ringFile rf = lpszFile; FILETIME fTime; ringDateTime rdt; rf.GetFileTime(NULL,NULL,&fTime); rdt = &fTime; char szText[40]; wsprintf(szText,"%d-%02d-%02d %02d:%02d",rdt.year(),rdt.month(),rdt.day(), rdt.hour(),rdt.minute()); m_statbar->SetValue(szText,1); } } void RINGMAINMETHOD(ListFile)() { //获取选择的目录后列出图象文件 ringDir dir(m_dirtree->GetSelFolderName()); ringFile rf; ringStr str; char szFile[MAX_PATH],szSize[40]; int index,nSubIdx,nSize,nData; FILETIME fTime; ringDateTime rdt; DWORD dwAttr,dwCheck; int nFileCnt=0,nTotalSize=0; if(IsWindowPtr(m_fileview)) //检测m_fileview是否有效及已创建 m_fileview->Clear(); if(dir.BeginFindFile()) { SHFILEINFO sfi; while(dir.FindNext(szFile)) { if(strcmp(szFile,"..") == 0) continue; rf.SetFile("%s\\%s",dir.Getdir(),szFile); str = rf.Extname(); str.toLower(); dwAttr = rf.GetAttrib() & (FILTER_FOLDER|FILTER_HIDDEN|FILE_ATTRIBUTE_ARCHIVE); dwCheck = m_dwFilter & dwAttr; if(MASK_MATCH(dwAttr,FILTER_HIDDEN) && !MASK_MATCH(dwCheck,FILTER_HIDDEN)) dwCheck = 0; if((dwAttr != 0xFFFFFFFF && dwCheck > 0) && (MASK_MATCH(dwCheck,FILTER_FOLDER) || (MASK_MATCH(m_dwFilter,FILTER_PIC) && (str == "bmp" || str == "jpg" || str == "jpeg" || str == "gif" || str == "pcx" || str == "png")) || MASK_MATCH(m_dwFilter,FILTER_OTHER))) { index = m_fileview->GetCount(); SHGetFileInfo((LPCTSTR)rf.Fullname(), 0, &sfi, sizeof(SHFILEINFO), SHGFI_SYSICONINDEX|SHGFI_SMALLICON| SHGFI_DISPLAYNAME|SHGFI_ATTRIBUTES|SHGFI_TYPENAME); nData = nSize = rf.Size(); nTotalSize += nSize; nFileCnt ++; if(nSize > 0) nSize = nSize/1024 + 1; if(!MASK_MATCH(sfi.dwAttributes,SFGAO_FOLDER)) { memset(szSize,0,40); int x = 1000000000; while(x > 1) { if(nSize/x > 0) wsprintf(szSize,"%s%d,",szSize,(nSize/x)%1000); x /= 1000; } wsprintf(szSize,"%s%dKB",szSize,nSize%1000); } else { wsprintf(szSize,"\0"); nData = -1; } //设置绑定数据,低位图标序号,高位为尺寸后三位,避免new一个 //结构完整记录这三个信息,按尺寸排序需要先比较字符串长度, //然后字符串,然后nData的高位 nData = MAKELONG(sfi.iIcon,nData%1000); m_fileview->AddItem(index,sfi.szDisplayName,nData,sfi.iIcon); nSubIdx = 1; m_fileview->SetItem(index,nSubIdx++,szSize); m_fileview->SetItem(index,nSubIdx++,sfi.szTypeName); rf.GetFileTime(NULL,NULL,&fTime); rdt = &fTime; wsprintf(szSize,"%d-%02d-%02d %02d:%02d",rdt.year(),rdt.month(),rdt.day(), rdt.hour(),rdt.minute()); m_fileview->SetItem(index,nSubIdx++,szSize); } } m_fileview->SortItemsEx(RINGCLASS(NavPane)::SortFileProc,(NavPane->m_nMarkCol==-1)); NavPane->UpdateFileList(); } int nRest=0; if(nTotalSize < 1000) wsprintf(szSize,"字节"); else if(nTotalSize < 1000000) { nRest = (nTotalSize%1000)/100; nTotalSize /= 1000; wsprintf(szSize,"KB"); } else { nRest = ((nTotalSize/1000)%1000)/100; nTotalSize /= 1000000; wsprintf(szSize,"MB"); } if(nRest == 0) wsprintf(szFile,"总计 %d 个文件(%d%s)",nFileCnt,nTotalSize,szSize); else wsprintf(szFile,"总计 %d 个文件(%d.%d%s)",nFileCnt,nTotalSize,nRest+1,szSize); m_statbar->SetValue(szFile,0); } RINGMAINMSG(WM_DESTROY) { //主窗口关闭时的清理代码,如果响应本消息,必须在最后调用Quit(), //即PostQuitMessage,否则窗口销毁,但程序仍滞留内存。 if(m_iconFile) { m_statbar->SetIcon(2,NULL); DestroyIcon(m_iconFile); } CoUninitialize(); return Quit(); } //绘制标签 RINGMAINMSG(WM_DRAWITEM) { if(param.lpdrawitem->CtlType == ODT_TAB) { if(param.lpdrawitem->itemAction == ODA_DRAWENTIRE) { RingTab* tab = NULL; if(param.wParam == IDC_NAVBAR) tab = m_navbar; else if(param.wParam == IDC_NAVPANE) tab = m_tab; if(tab) { LPSTR lps = (LPSTR)tab->GetText(param.lpdrawitem->itemID); int len = strlen(lps); SetBkMode(param.lpdrawitem->hDC,TRANSPARENT); if(param.lpdrawitem->itemState == ODS_SELECTED) DrawText(param.lpdrawitem->hDC,lps,len,¶m.lpdrawitem->rcItem,DT_SINGLELINE|DT_CENTER|DT_VCENTER); else DrawText(param.lpdrawitem->hDC,lps,len,¶m.lpdrawitem->rcItem,DT_SINGLELINE|DT_CENTER|DT_BOTTOM); } } } return TRUE; } RINGMAINCMD(OnOpen) { //这里添加打开文件代码... } RINGMAINCMD(OnExit) { //发送程序退出消息 SendExit(); } RINGMAINCMD(OnHelp) { //标准对话框调用代码 DlgAbout = NewRingObj(DlgAbout); DlgAbout->DoModal(); //如果窗口类未设置自动销毁(调用SetAutoDelete),则需要销毁对象 DelRingObj(DlgAbout); } RINGMAINCMD(OnSetViewMode) { //设置文件列表查看方式 NavPane->OnSetViewMode(event); } RINGMAINCMD(OnSetFileFilter) { //设置文件过滤 RingCoolMenu* rm = GetCoolMenu(); BOOL bCheck = FALSE; if(rm) { rm = rm->SubMenu(2)->SubMenu(1); bCheck = !MASK_MATCH(rm->GetItemCheckState(event),MFS_CHECKED); rm->CheckItem(event,bCheck); switch(event) { case CM_SHOWFOLDER: if(bCheck) m_dwFilter |= FILTER_FOLDER; else m_dwFilter &= ~FILTER_FOLDER; break; case CM_SHOWPIC: if(bCheck) m_dwFilter |= FILTER_PIC; else m_dwFilter &= ~FILTER_PIC; break; case CM_SHOWALBUM: if(bCheck) m_dwFilter |= FILTER_ALBUM; else m_dwFilter &= ~FILTER_ALBUM; break; case CM_SHOWMEDIA: if(bCheck) m_dwFilter |= FILTER_MEDIA; else m_dwFilter &= ~FILTER_MEDIA; break; case CM_SHOWOTHER: if(bCheck) m_dwFilter |= FILTER_OTHER; else m_dwFilter &= ~FILTER_OTHER; break; case CM_SHOWHIDDEN: if(bCheck) m_dwFilter |= FILTER_HIDDEN; else m_dwFilter &= ~FILTER_HIDDEN; break; } ListFile(); } } RINGMAINCMD(OnSetColumn) { //显示/隐藏文件列表列,为RingListView的扩展特性 RingCoolMenu* rm = GetCoolMenu(); BOOL bCheck = FALSE; int idx = event-CM_COLSIZE; int nIndex = idx + 1; if(rm) { rm = rm->SubMenu(2)->SubMenu(2); bCheck = !MASK_MATCH(rm->GetItemCheckState(event),MFS_CHECKED); rm->CheckItem(event,bCheck); m_fileview->ShowColumn(nIndex,bCheck); } } RINGMAINCMD(OnSortColumn) { //选择排序 NavPane->OnSortColumn(event); } BOOL RingTabEx::OnDrawBkg(HDC hDC) { //获取停靠坞背景,计算位置偏移进行绘制,保持整个窗口背景一致 RingDockSite* tmp = ((RingWnd*)Parent())->GetDockSite(TBS_FLAG_DOCKTOP); RECT rc; SIZE offset={0,0}; if(tmp) { Parent()->GetClientRect(&rc); offset.cx = rc.left; offset.cy = rc.top; OffsetRect(&rc,-rc.left,-rc.top); return tmp->DrawBkg(hDC,&rc,&offset); } return FALSE; }